﻿// ***********************************************************************
// Assembly         : GooglePredict
// Author           : aj
// Created          : 10-08-2010
//
// Last Modified By : aj
// Last Modified On : 10-11-2010
// Description      : 
//
//
// ***********************************************************************
namespace Google.API.Predict
{
    using Auth;
    using Requests;
    using Requests.Core;
    using Requests.Features;
    using Responses;

    /// <summary>
    /// Wrapper class for underlying code, brings it all together, hides complexity.
    /// </summary>
    public class GooglePredictionClient : IGooglePredictionClient
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="GooglePredictionClient"/> class.
        /// </summary>
        /// <param name="login">The login.</param>
        /// <param name="password">The password.</param>
        /// <param name="bucket">The bucket.</param>
        /// <param name="data">The data.</param>
        public GooglePredictionClient(string login, string password, string bucket, string data)
        {
            ClientLogin = ClientLoginRequest.Authenticate(login, password);
            Bucket = bucket;
            Data = data;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="GooglePredictionClient"/> class.
        /// </summary>
        /// <param name="clientLogin">The client login.</param>
        /// <param name="bucket">The bucket.</param>
        /// <param name="data">The data.</param>
        public GooglePredictionClient(ClientLoginResponse clientLogin, string bucket, string data)
        {
            ClientLogin = clientLogin;
            Bucket = bucket;
            Data = data;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="GooglePredictionClient"/> class.
        /// </summary>
        /// <param name="auth">The auth.</param>
        /// <param name="bucket">The bucket.</param>
        /// <param name="data">The data.</param>
        public GooglePredictionClient(string auth, string bucket, string data)
        {
            ClientLogin = ClientLoginResponse.CreateFromAuth(auth);
            Bucket = bucket;
            Data = data;
        }

        #region IGooglePrediction Members

        /// <summary>
        /// Gets the client login.
        /// </summary>
        /// <value>The client login.</value>
        public ClientLoginResponse ClientLogin { get; private set; }

        /// <summary>
        /// Gets the bucket.
        /// </summary>
        /// <value>The bucket.</value>
        public string Bucket { get; private set; }

        /// <summary>
        /// Gets the data.
        /// </summary>
        /// <value>The data.</value>
        public string Data { get; private set; }

        /// <summary>
        /// Changes the bucket and data values
        /// </summary>
        /// <param name="bucket">The bucket.</param>
        /// <param name="data">The data.</param>
        public void ChangeData(string bucket, string data)
        {
            Bucket = bucket;
            Data = data;
        }

        /// <summary>
        /// Requests the specified request.
        /// </summary>
        /// <typeparam name="TResponseType"></typeparam>
        /// <param name="request">The request.</param>
        public void Request<TResponseType>(GooglePredictionApiRequest<TResponseType> request) where TResponseType : BaseResponse, new()
        {
            request.Auth = ClientLogin.Auth;

            if (string.IsNullOrEmpty(request.Bucket))
                request.Bucket = Bucket;

            if (string.IsNullOrEmpty(request.Data))
                request.Data = Data;

            request.Execute();
        }

        /// <summary>
        /// Retrieve meta data about the current model
        /// </summary>
        /// <returns>MetadataResponse</returns>
        public MetadataResponse Check()
        {
            var m = new MetadataRequest();
            Request(m);
            return m.Response;
        }

        /// <summary>
        /// Initiate training
        /// </summary>
        /// <returns>TrainingResponse</returns>
        public TrainingResponse Train()
        {
            var m = new TrainingRequest();
            Request(m);
            return m.Response;
        }

        /// <summary>
        /// POST a mixed prediction request (numeric and text)
        /// </summary>
        /// <param name="value">Object containing values to send</param>
        /// <returns></returns>
        public PredictionResponse PredictMixed(MixedFeatures value)
        {
            var m = new PredictionRequest<MixedFeatures>(value);
            Request(m);
            return m.Response;
        }

        /// <summary>
        /// POST a regression prediction request (numeric only)
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public PredictionResponse PredictNumeric<T>(NumericFeatures<T> value)
        {
            var m = new PredictionRequest<NumericFeatures<T>>(value);
            Request(m);
            return m.Response;
        }

        /// <summary>
        /// POST a categorical prediction request (text only)
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public PredictionResponse PredictText(TextFeatures value)
        {
            var m = new PredictionRequest<TextFeatures>(value);
            Request(m);
            return m.Response;
        }

        public DeleteResponse Delete()
        {
            var dr = new DeleteRequest();
            Request(dr);
            return dr.Response;
        }
        #endregion
    }
}
